﻿using System;
using System.Linq;

using Buddy.BehaviorTree;
using Buddy.Common;
using Buddy.CommonBot;
using Buddy.Swtor;
using Buddy.Swtor.Objects;

using WingIt;
using WingIt.Dynamics;
using WingIt.Routines.Mirrors;

using Action = Buddy.BehaviorTree.Action;

namespace WingIt.Routines
{//by protpally
    [RevisionControlId("$Id: AdvancedPrototype_Tactics.cs 686 2012-08-12 16:12:20Z Chinajade $")]
    public class PowertechAdvancedPrototype_VanguardTactics : MirrorRoutine
    {
        // MAINTAINERS NOTES:
        // * You will notice that lambda expression argument names are unique (e.g., "darkWardOn", "darkWardWhen", "joltWhen"),
        //   instead of generic (e.g., "ctx", "ret", "on", "doWhen", "castWhen").  PLEASE honor this convention!
        //   This allows us to quickly localize problems when looking at user's logs.  When the BehaviorTree encounters an exception
        //   (e.g., "object not found"), the location where an exception is thrown is identifiable only through the name
        //   of the lambda expression argument.  Such is the nature of BehaviorTrees.

        [Behavior(BehaviorType.Pull)]
        [Class(CharacterClass.BountyHunter, AdvancedClass.Powertech, SkillTreeId.PowertechAdvanced)]
        [Class(CharacterClass.Trooper, AdvancedClass.Vanguard, SkillTreeId.VanguardTactics)]
        public static Composite PowertechAdvancedPrototype_VanguardTactics_Pull()
        {
            return new PrioritySelector(
                // Gates
                LazyRaider.CreateBTPS_NotifyAndShortCircuitWhenCombatDisabled(),
                CreateBTPS.BWcoreFixup_WaitForHarvestComplete(),
                TargetSelect.CreateBTPS_UpdateForBattlefieldConditions(),

                // Prep
                CreateBTPS.BWcoreFixup_Dismount(),
                CreateBTPS.ApplyGuard(applyGuardWhen => Me.HasMirrorBuff("Ion Cell")),

                // Engage
                PowertechAdvancedPrototype_VanguardTactics_Combat()
                );
        }

        [Behavior(BehaviorType.Combat)]
        [Class(CharacterClass.BountyHunter, AdvancedClass.Powertech, SkillTreeId.PowertechAdvanced)]
        [Class(CharacterClass.Trooper, AdvancedClass.Vanguard, SkillTreeId.VanguardTactics)]
        public static Composite PowertechAdvancedPrototype_VanguardTactics_Combat()
        {
            return new PrioritySelector(
                LazyRaider.CreateBTPS_NotifyAndShortCircuitWhenCombatDisabled(),
                TargetSelect.CreateBTPS_UpdateForBattlefieldConditions(),

                // We may be mounted (and no Companion out) at the pull.  So, we have to wait until combat to try to apply guard.
                CreateBTPS.ApplyGuard(applyGuardWhen => Me.HasMirrorBuff("Ion Cell")),

                #region Movement
                CreateBTPS.MoveWithinRangeAndLoS(target => MyTarget, 0.5f),
                CreateBTPS.StopWithinRangeAndLoS(target => MyTarget, 0.5f),
                #endregion

                new Decorator(whenLowResources => Resource < 25,
                    new Action(burnPhaseOff => LazyRaider.BurnPhaseOff())
                ),

                #region Burn Phase
                new Decorator(whenBurnPhaseEnabled => LazyRaider.IsBurnPhaseEnabled || MeHasConsumableBuff("Critical Boost") || MeHasConsumableBuff("Power Boost"),
                    new PrioritySelector(
                        Cast("Gut", gutWhen => !MyTarget.HasMirrorDebuffStacks("Bleeding (Physical)", 1, d => d.TimeLeft > TimeSpan.FromSeconds(4))),
                        new Decorator(targetNotInRange => !MyTarget.IsInRange(0.5f),
                            new PrioritySelector(
                                Cast("Harpoon", harpoonWhen => !Me.IsMoving),
                                CreateBTPS.MoveWithinRangeAndLoS(target => MyTarget, 0.5f)
                            )
                        ),
                        new Decorator(targetInrange => MyTarget.IsInRange(1f),
                            new Sequence(
                                new Action(doFace => MyTarget.Face()),
                                Cast("Pulse Cannon", pulseCannonWhen => MyTarget.IsInRange(1f))//Frontal Cone
                            )
                        ),
                        Cast("High Impact Bolt", highImpactBoltWhen => Resource >= 17 && Me.HasMirrorBuff("Combat Tactics")),
                        Cast("Stockstrike", stockstrikeWhen => Resource >= 17 && MyTarget.IsInRange(0.5f) && Me.HasMirrorBuff("Battering Ram")),
                        Cast("Fire Pulse", firePulseWhen => Resource >= 17),
                        Cast("Stockstrike", stockStrikeWhen => Resource >= 17 && MyTarget.IsInRange(0.5f)),
                        Cast("High Impact Bolt", highImpactBoltWhen => Resource >= 17),
                        Cast("Ion Pulse")
                    )
                ),
                #endregion

                #region Lazyraiderish stuff - works with combat movement off
                new Decorator(whenNotMoving => Me.IsMoving,
                    new PrioritySelector(
                        Cast("Gut", gutWhen => !MyTarget.HasMirrorDebuffStacks("Bleeding (Physical)", 1, d => d.TimeLeft > TimeSpan.FromSeconds(4))),
                        BuffSelf("Reactive Shield", reactiveShieldWhen => Me.HealthPercent < 40),
                        Cast("Adrenaline Rush", adrenalineRushWhen => Me.HealthPercent <= 60),
                        Cast("Hammer Shot", hammerShotWhen => Resource < 75 && !(LazyRaider.IsBurnPhaseEnabled || MeHasConsumableBuff("Critical Boost") || MeHasConsumableBuff("Power Boost"))),
                        Cast("High Impact Bolt"),
                        Cast("Sticky Grenade"),
                        Cast("Hammer Shot", hammerShotWhen => !(LazyRaider.IsBurnPhaseEnabled || MeHasConsumableBuff("Critical Boost") || MeHasConsumableBuff("Power Boost")))
                    )
                ),
                #endregion

                new Decorator(whenBurnPhaseDisabled => !LazyRaider.IsBurnPhaseEnabled || !MeHasConsumableBuff("Critical Boost") || !MeHasConsumableBuff("Power Boost"),
                    new PrioritySelector(
                        Cast("Recharge Cells", rechargeCellsWhen => Resource <= 50),
                        Cast("Gut", gutWhen => !MyTarget.HasMirrorDebuffStacks("Bleeding (Physical)", 1, d => d.TimeLeft > TimeSpan.FromSeconds(4))),
                        Cast("Tenacity", tenacityWhen => Me.IsStunned),
                        BuffSelf("Reactive Shield", reactiveShieldWhen => Me.HealthPercent < 40),
                        Cast("Adrenaline Rush", adrenalineRushWhen => Me.HealthPercent <= 60),
                        Cast("Hammer Shot", hammerShotWhen => Resource < 75),
                        new Decorator(whenTargetNotInRange => !MyTarget.IsInRange(0.5f),
                            new PrioritySelector(
                                Cast("Harpoon", harpoonWhen => !Me.IsMoving),
                                CreateBTPS.MoveWithinRangeAndLoS(target => MyTarget, 0.5f)
                            )
                        ),
                        new Decorator(whenTargetInRange => MyTarget.IsInRange(1f),
                            new Sequence(
                                new Action(doFace => MyTarget.Face()),
                                Cast("Pulse Cannon", pulseCannonWhen => MyTarget.IsInRange(1f))//Frontal Cone
                            )
                        ),
                        Cast("High Impact Bolt", highImpactBoltWhen => Resource >= 17 && Me.HasMirrorBuff("Combat Tactics")),
                        Cast("Stockstrike", stockstrikeWhen => Resource >= 17 && MyTarget.IsInRange(0.5f) && Me.HasMirrorBuff("Battering Ram")),
                        Cast("Fire Pulse", firePulseWhen => Resource >= 17),
                        Cast("Stockstrike", stockstrikeWhen => Resource >= 17 && MyTarget.IsInRange(0.5f)),
                        Cast("High Impact Bolt", highImpactBoltWhen => Resource >= 17),
                        Cast("Ion Pulse", ionPulseWhen => Resource >= 84),
                        Cast("Recharge Cells", rechargeCellsWhen => Resource < 17),
                        Cast("Hammer Shot")
                    )
                )
            );
        }
        
        [Behavior(BehaviorType.OutOfCombat)]
        [Class(CharacterClass.BountyHunter, AdvancedClass.Powertech, SkillTreeId.PowertechAdvanced)]
        [Class(CharacterClass.Trooper, AdvancedClass.Vanguard, SkillTreeId.VanguardTactics)]
        public static Composite PowertechAdvancedPrototype_VanguardTactics_OutOfCombat()
        {
            // NB: Apparently, BWcore will call this routine when in combat on occasion.  It is also called while we're pulling.
            return (new PrioritySelector(
                TargetSelect.CreateBTPS_UpdateForBattlefieldConditions(),
                new Decorator(oocBuffWhen => !Me.IsMounted,
                    new PrioritySelector(
                        BuffSelf("High Energy Cell"),
                        BuffSelf("Plasma Cell", plasmaCellWhen => !Me.HasMirrorAbility("High Energy Cell")),
                        CreateBTPS.ApplyGuard(applyGuardWhen => Me.HasMirrorBuff("Ion Cell"))
                        ))
                ));
        }
    }
}
